#ifndef _FORCES_H_
#define _FORCES_H_

#include "world_entity.h"
#include "../../common/vector.h"

#include <vector>

using namespace std;

/* design pattern: interface
 * usiamo questa classe per implementare tutti i vari generatori di forze
 * che verranno applicati alle entita'
 */
class ForceGenerator
{
	public:
		virtual ~ForceGenerator(void);
		virtual void updateForce(WorldEntity *entity, double delta) = 0;
		
};

/* registro dei generatori: viene utilizzato per tenere
 * traccia di quali entita' sono soggette a quali forze
 */
class ForceRegistry
{
	protected:
		struct ForceRegistration
		{
			WorldEntity *entity;
			ForceGenerator *forceGen;
		};
		
		typedef vector<ForceRegistration> Registry;
		Registry registry; 
		
	public:
		ForceRegistry(void);
		/* aggiunge una connessione tra un'entita' e un generatore */
		void add(WorldEntity *entity, ForceGenerator *gen);
		/* rimuove una connessione tra un'entita' e un generatore */
		void remove(WorldEntity *entity, ForceGenerator *gen);
		/* svuota tutte le connessioni */
		void clear();
		/* aggiorna le forze */
		void updateForces(double delta);
	
};

/* generatore di forza per la gravita' */
class GravityGenerator : ForceGenerator
{
	private:
		Vector2D m_gravity;
	
	public:
		GravityGenerator(const Vector2D &gravity);
		~GravityGenerator(void);
		virtual void updateForce(WorldEntity *entity, float delta);
};

/* generatore di forza per l'attrito */
class DragGenerator : ForceGenerator
{
	private:
		/* coefficienti di attrito
		 * k1 = coefficiente relativo alla velocita'
		 * k2 = coefficiente relativo alla velocita' al quadrato
		 */
		float m_k1, m_k2;
		
	public:
		DragGenerator(float k1, float k2);
		~DragGenerator(void);
		virtual void updateForce(WorldEntity *entity, float delta);	
};

#endif
